var Job = Class.create({
			initialize : function(closure, delay, timeout) {
				this.run = closure;
				this.waitId = 0;
				this.isDone = false;
				this.delay = delay;
				this.timeout = timeout;
				this.id = null;
				if (typeof(delay) == 'undefined')
					this.delay = 500;
			},

			schedule : function(delay) {
				this.cancel();
				this.id = randomString();
				this.schedTime = new Date();
				var self = this;
				if (typeof(delay) == 'undefined')
					delay = this.delay;
				var closure = function() {
					self.waitId = null;
					self.isDone = false;
					self.schedTime = false;
					if (self.timeout) {
						loadingAnimation.start();
						self.timeoutId = window.setTimeout(function() {
									self.cancel();
								}, self.timeout + 1);
					}
					self.run();
				};
				this.waitId = window.setTimeout(closure, delay);
				return this.id;
			},

			replaceSchedule : function(delay) {
				if (typeof(delay) == 'undefined')
					delay = this.delay;
				if (this.isDone) {
					return this.schedule(delay);
				}
				if (this.schedTime) {
					var wait = new Date() - this.schedTime;
					wait = delay - wait;
					if (wait < 0)
						wait = 0;
					this.cancelSchedule();
					this.schedule(wait);
				} else {
					this.cancel();
					this.schedule(0);
				}
				return this.id;
			},

			cancelSchedule : function() {
				if (this.waitId)
					window.clearTimeout(this.waitId);
				if (this.timeoutId) {
					window.clearTimeout(this.timeoutId);
					loadingAnimation.stop();
				}
				this.waitId = null;
				this.id = null;
			},

			cancel : function() {
				if (!this.id)
					return;
				this.cancelSchedule();
				if (!this.isDone)
					this.doCancel();
				try {
					this.postCancel.apply(this, arguments);
				} catch (e) {
					console.dir(e.stack || e);
				}
				this.id = null;
			},

			done : function() {
				if (!this.id)
					return;
				if (this.timeoutId) {
					window.clearTimeout(this.timeoutId);
					loadingAnimation.stop();
				}
				this.isDone = true;
			},

			doCancel : function() {

			},

			postCancel : function() {

			}
		});
